package com.srmt.feishu.client;

import com.lark.oapi.service.sheets.v3.model.*;
import com.srmt.feishu.client.model.ProtectedDimension;
import java.util.List;
import java.util.Map;

/**
 * 电子表格服务接口
 *
 * 提供对飞书电子表格的操作能力，包括：
 * - 获取电子表格信息
 * - 读写单元格数据
 * - 操作工作表
 * - 维度操作（行列增删）
 *
 * <h3>重构说明（v6.0.0）：</h3>
 * <ul>
 *   <li>v3 API方法返回具体数据类型，不再返回Resp对象</li>
 *   <li>v2 API方法保持不变（已经是具体类型）</li>
 *   <li>响应校验统一在服务层处理</li>
 *   <li>失败时统一抛出FeishuApiException</li>
 * </ul>
 *
 * @author SRMT Development Team
 * @since 3.0.0
 * @version 6.0.0 统一响应处理层重构
 */
public interface SheetsService {

    // ========== 基础信息查询 (v3 API - 已重构) ==========

    /**
     * 获取电子表格的工作表信息
     *
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @return 工作表对象
     * @throws com.srmt.feishu.client.exception.FeishuApiException 如果API调用失败
     * @throws Exception 如果其他错误
     */
    Sheet getSheet(String spreadsheetToken, String sheetId) throws Exception;

    /**
     * 获取电子表格信息
     *
     * @param spreadsheetToken 电子表格token
     * @return 电子表格对象
     * @throws com.srmt.feishu.client.exception.FeishuApiException 如果API调用失败
     * @throws Exception 如果其他错误
     */
    com.lark.oapi.service.sheets.v3.model.GetSpreadsheet getSpreadsheet(String spreadsheetToken) throws Exception;

    /**
     * 查询电子表格的所有工作表
     *
     * @param spreadsheetToken 电子表格token
     * @return 工作表数组
     * @throws com.srmt.feishu.client.exception.FeishuApiException 如果API调用失败
     * @throws Exception 如果其他错误
     */
    Sheet[] querySheets(String spreadsheetToken) throws Exception;

    /**
     * 创建新的电子表格
     *
     * @param req 创建请求
     * @return 创建的电子表格对象
     * @throws com.srmt.feishu.client.exception.FeishuApiException 如果API调用失败
     * @throws Exception 如果其他错误
     */
    com.lark.oapi.service.sheets.v3.model.Spreadsheet createSpreadsheet(CreateSpreadsheetReq req) throws Exception;
    
    // ========== 数据读写操作 ==========
    
    /**
     * 读取单个范围的数据
     * 对应API: GET /sheets/v2/spreadsheets/:spreadsheetToken/values/:range
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围（如"Sheet1!A1:B2"）
     * @return 值数组
     * @throws Exception 如果操作失败
     */
    List<List<String>> getValues(String spreadsheetToken, String range) throws Exception;
    
    /**
     * 向单个范围写入数据（覆盖原有数据）
     * 对应API: PUT /sheets/v2/spreadsheets/:spreadsheetToken/values
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围（如"Sheet1!A1:B2"）
     * @param values 要写入的值
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean updateValues(String spreadsheetToken, String range, List<List<String>> values) throws Exception;
    
    /**
     * 批量更新多个范围的数据
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/values_batch_update
     * 
     * @param spreadsheetToken 电子表格token
     * @param updates 更新映射（range -> values）
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean batchUpdateValues(String spreadsheetToken, Map<String, List<List<String>>> updates) throws Exception;
    
    /**
     * 在指定范围上方插入数据（会新增行）
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/values_prepend
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围（如"Sheet1!A1:B2"）
     * @param values 要插入的值
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean prependValues(String spreadsheetToken, String range, List<List<String>> values) throws Exception;
    
    /**
     * 追加数据到工作表
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/values_append
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围（如"Sheet1!A1:B2"）
     * @param values 要追加的值
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean appendValues(String spreadsheetToken, String range, List<List<String>> values) throws Exception;
    
    // ========== 维度操作（行列） ==========
    
    /**
     * 增加空白行或列
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/dimension_range
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param dimension 维度（"ROWS"或"COLUMNS"）
     * @param length 要增加的数量
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean addDimensionRange(String spreadsheetToken, String sheetId, String dimension, int length) throws Exception;
    
    /**
     * 插入空白行或列
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/insert_dimension_range
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param dimension 维度（"ROWS"或"COLUMNS"）
     * @param startIndex 起始索引
     * @param endIndex 结束索引（不包含）
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean insertDimensionRange(String spreadsheetToken, String sheetId, String dimension, 
                                int startIndex, int endIndex) throws Exception;
    
    /**
     * 删除行或列
     * 对应API: DELETE /sheets/v2/spreadsheets/:spreadsheetToken/dimension_range
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param dimension 维度（"ROWS"或"COLUMNS"）
     * @param startIndex 起始索引
     * @param endIndex 结束索引（不包含）
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean deleteDimensionRange(String spreadsheetToken, String sheetId, String dimension,
                                int startIndex, int endIndex) throws Exception;
    
    /**
     * 更新行高或列宽
     * 对应API: PUT /sheets/v2/spreadsheets/:spreadsheetToken/dimension_range
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param dimension 维度（"ROWS"或"COLUMNS"）
     * @param startIndex 起始索引
     * @param endIndex 结束索引（不包含）
     * @param size 新的高度或宽度（像素）
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean updateDimensionRange(String spreadsheetToken, String sheetId, String dimension,
                                int startIndex, int endIndex, int size) throws Exception;
    
    // ========== 单元格操作 ==========
    
    /**
     * 合并单元格
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/merge_cells
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param startRow 起始行
     * @param startCol 起始列
     * @param endRow 结束行
     * @param endCol 结束列
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean mergeCells(String spreadsheetToken, String sheetId,
                      int startRow, int startCol, int endRow, int endCol) throws Exception;
    
    /**
     * 取消合并单元格
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/unmerge_cells
     * 
     * @param spreadsheetToken 电子表格token
     * @param sheetId 工作表ID
     * @param startRow 起始行
     * @param startCol 起始列
     * @param endRow 结束行
     * @param endCol 结束列
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean unmergeCells(String spreadsheetToken, String sheetId,
                        int startRow, int startCol, int endRow, int endCol) throws Exception;
    
    // ========== 格式设置 ==========
    
    /**
     * 设置单元格格式
     * 对应API: PUT /sheets/v2/spreadsheets/:spreadsheetToken/style
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围
     * @param style 样式对象
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean setCellStyle(String spreadsheetToken, String range, Object style) throws Exception;
    
    /**
     * 设置数据验证
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/dataValidation
     * 
     * @param spreadsheetToken 电子表格token
     * @param range 范围
     * @param validation 验证规则
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean setDataValidation(String spreadsheetToken, String range, Object validation) throws Exception;
    
    // ========== 保护范围操作 ==========
    
    /**
     * 添加保护范围
     * 对应API: POST /sheets/v2/spreadsheets/:spreadsheetToken/protected_dimension
     * 
     * @param spreadsheetToken 电子表格token
     * @param protectedDimensions 保护维度列表
     * @param userIdType 用户ID类型（open_id, union_id, user_id）
     * @return 是否成功
     * @throws Exception 如果操作失败
     */
    boolean addProtectedDimension(String spreadsheetToken, 
                                 List<ProtectedDimension> protectedDimensions,
                                 String userIdType) throws Exception;
}